﻿using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace MyK3CloudCore.IOC.K3Client;

/// <summary>
/// 客户端
/// </summary>
public class K3CloudHttpClient
{
    /// <summary>
    /// k3服务基地址
    /// </summary>
    public string BaseUrl { get; set; }
    /// <summary>
    /// url路径
    /// </summary>
    public string Path { get; set; }
    /// <summary>
    /// 正文
    /// </summary>
    public string Content { get; set; }

    private readonly IHttpClientFactory httpClient;
    public K3CloudHttpClient()
    {
        this.httpClient = K3Scoped.HttpFactory;
    }

    public async Task<string> PostAsync(CancellationToken cancellationToken = default)
    {
        //Debug.WriteLine("===============Post================");
        //Debug.WriteLine(Url);
        //Debug.WriteLine(Content);
        //Debug.WriteLine("===============Post  End==============");
        //var co = K3Scoped.Cookie.GetCookies(new Uri(BaseUrl)).Cast<Cookie>().ToList();
        var ctsForTimeout = new CancellationTokenSource();
        ctsForTimeout.CancelAfter(TimeSpan.FromMinutes(10));
        var cancellationTokenForTimeout = ctsForTimeout.Token;
        using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancellationTokenForTimeout);
        try
        {
            using HttpClient client = httpClient.CreateClient(IocConst.K3WEBAPI_CLIENT);
            client.Timeout = Timeout.InfiniteTimeSpan;
            JObject jObj = new()
            {
                { "format", 1 },
                { "useragent", "ApiClient" },
                { "rid", Math.Abs(Guid.NewGuid().GetHashCode()) },
                { "parameters", Content },
                { "timestamp", DateTimeFormatUtils.CurrentTimeMillis() },
                { "v", "1.0" }
            };
            string sContent = jObj.ToString();
            HttpContent stringContent = new StringContent(sContent);
            stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
            var result = await client.PostAsync(ResolveUrl(Path), stringContent, linkedCts.Token);
            result.EnsureSuccessStatusCode();
            return ValidateResult(await result.Content.ReadAsStringAsync());
        }
        catch
        {
            if (cancellationTokenForTimeout.IsCancellationRequested)
            {
                Console.WriteLine("timeout");
            }
            else if (cancellationToken.IsCancellationRequested)
            {
                Console.WriteLine("other cancellation token cancelled");
            }
            throw;
        }
        finally
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

    }

    public async Task<string> GetAsync(CancellationToken cancellationToken = default)
    {
        try
        {
            var ctsForTimeout = new CancellationTokenSource();
            ctsForTimeout.CancelAfter(TimeSpan.FromMinutes(10));
            var cancellationTokenForTimeout = ctsForTimeout.Token;
            using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancellationTokenForTimeout);
            using HttpClient client = httpClient.CreateClient(IocConst.K3WEBAPI_CLIENT);
            client.Timeout = Timeout.InfiniteTimeSpan;
            var result = await client.GetAsync(ResolveUrl(Path), linkedCts.Token);
            result.EnsureSuccessStatusCode();
            return ValidateResult(await result.Content.ReadAsStringAsync());
        }
        catch (Exception)
        {
            throw;
        }
    }
    /// <summary>
    /// url拼接
    /// </summary>
    /// <returns></returns>
    private string ResolveUrl(string path)
    {
        if (path.ToLower().StartsWith("http://")
            || path.ToLower().StartsWith("https://")
            ) { return path; }
        var baseUrl = this.BaseUrl.TrimEnd('/');
        string fullUrl;
        if (path.StartsWith('/'))
        {
            fullUrl = baseUrl + path;
        }
        else
        {
            fullUrl = $"{baseUrl}/{path}";
        }
        return fullUrl;
    }
    private static string ValidateResult(string responseText)
    {
        if (responseText.StartsWith("response_error:", StringComparison.OrdinalIgnoreCase))
        {
            return responseText.TrimStart("response_error:".ToCharArray());
        }
        return responseText;
    }
}